#pragma once

#include <string_view>
#include <string>
#include <vector>

#include <git2/remote.h>

#include "util/fs.h"

#include "git-head.h"

struct git_repository;
struct git_clone_options;

namespace git
{

class Repo
{
public:
    Repo() {}

    Repo(const std::string_view &localPath);

    Repo(const std::string_view &localPath, const std::string_view &uri, const Cert &cert);

    ~Repo();

    operator bool() const {
        return repo_ != nullptr;
    }

    void open(const std::string_view &uri, const Cert &cert);

    void close(const char *reason);

    Head head() const;

    void logDump() const;

    void pull(const Cert &cert);

    void merge(const Branch &other);

private:
    const std::string &title() const {
        return title_;
    }

    git_repository *openExistedLocalRepo() const;

    git_repository *cloneRemoteRepo(const std::string_view &uri, const Cert &cert) const;

    git_repository *doOpen(const std::string_view &uri, const Cert &cert) const;

    void fillGitCloneOption(git_clone_options &opt) const;

    void fillGitFetchOption(git_fetch_options &opt) const;

    bool isHeadDetached() const;

private:
    const fs::path abspath_;
    const std::string title_;
    git_repository *repo_ = nullptr;
};

} // namespace git
